/*  This file is part of -_-.

    -_- is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    -_- is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with -_-.  If not, see <http://www.gnu.org/licenses/>.

    Copyright 2012-2013 Oliver Katz */

#include "fio.h"
#include "debug.h"

z_freader z_freader_init(char *path, int bufsize)
{
	z_freader tmp;
	tmp.path = path;
	tmp.handle = fopen(path, "r");
	if (tmp.handle == NULL)
	{
		tmp.buffer = NULL;
		Z_WARNING("cannot open file (%s)", path);
		return tmp;
	}
	fseek(tmp.handle, 0, SEEK_END);
	tmp.length = ftell(tmp.handle);
	fseek(tmp.handle, 0, SEEK_SET);
	if (bufsize > 0)
		tmp.bufsize = (z_size)bufsize;
	else if (bufsize < 0)
		tmp.bufsize = tmp.length+1;
	else
		tmp.bufsize = Z_FIO_BUFSIZE_DEFAULT;
	tmp.buffer = (char *)malloc(sizeof(char)*tmp.bufsize);
	return tmp;
}

z_freader *z_freader_new(char *path, int bufsize)
{
	z_freader *tmp = (z_freader *)malloc(sizeof(z_freader));
	*tmp = z_freader_init(path, bufsize);
	return tmp;
}

int z_freader_release(z_freader f)
{
	if (f.handle != NULL)
		fclose(f.handle);
	if (f.buffer != NULL)
		free(f.buffer);
	return 0;
}

int z_freader_delete(z_freader *f)
{
	Z_WARNING_NULL(f, 1);
	z_freader_release(*f);
	free(f);
	return 0;
}

int z_freader_ok(z_freader *f)
{
	Z_WARNING_NULL(f, 0);
	return (f->handle != NULL);
}

z_data z_freader_read(z_freader *f)
{
	Z_WARNING_NULL(f, z_data_init(0, 0));
	z_data tmp = z_data_init(Z_TYPEID_STR, f->bufsize*sizeof(char));
	memset(f->buffer, 0, sizeof(char)*f->bufsize);
	fread(f->buffer, sizeof(char), f->bufsize, f->handle);
	tmp.src = strdup(f->buffer);
	return tmp;
}

z_data *_z_freader_read(z_freader *f)
{
	Z_WARNING_NULL(f, NULL);
	z_data *tmp = (z_data *)malloc(sizeof(z_data));
	*tmp = z_freader_read(f);
	return tmp;
}

z_size z_freader_left(z_freader *f)
{
	Z_WARNING_NULL(f, 0);
	if (feof(f->handle))
		return 0;
	return f->length - ftell(f->handle);
}
